package com.zhoug.viewpermission;

import android.os.Build;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 *
 * @author: zhoug
 * @since: 2025-06-13
 */
public class MenuOwnerHelper {
    private MenuRepository mMenuRepository;
    private Object mOwner;
    /**
     * 菜单配置
     */
    private final BindMenuBean mBindMenuBean = new BindMenuBean();

    /**
     * 权限改变监听
     */
    private final List<OnPermissionChangeListener> mListener = new ArrayList<>();
    /**
     * 当前权限
     */
    private final List<ViewPermission> mPermissions = new ArrayList<>();
    private Callback<NavigationMenu> menuCallback;
    private NavigationMenu mMenu;

    public MenuOwnerHelper() {
        mMenuRepository = new MenuRepository();
    }

    public MenuOwnerHelper(Object owner) {
        this();
        setOwner(owner);
    }

    public MenuOwnerHelper setOwner(Object owner) {
        this.mOwner = owner;
        if (owner instanceof LifecycleOwner lifecycleOwner) {
            setLifecycleOwner(lifecycleOwner);
        }
        parseBindMenu();
        return this;

    }

    public MenuOwnerHelper setLifecycleOwner(LifecycleOwner lifecycleOwner) {
        if (lifecycleOwner != null) {
            lifecycleOwner.getLifecycle().addObserver(new DefaultLifecycleObserver() {
                @Override
                public void onDestroy(@NonNull LifecycleOwner owner) {
                    MenuOwnerHelper.this.onDestroy();
                }
            });
        }
        return this;
    }

    /**
     * 设置菜单路由
     *
     * @param path
     * @return
     */
    public MenuOwnerHelper setPath(String path) {
        mBindMenuBean.setPath(path);
        return this;
    }

    /**
     * 设置菜单编码
     *
     * @param code
     * @return
     */
    public MenuOwnerHelper setCode(String code) {
        mBindMenuBean.setCode(code);
        return this;
    }

    /**
     * 设置菜单主要权限
     *
     * @param permissionKey
     * @return
     */
    public MenuOwnerHelper setPermissionKey(String permissionKey) {
        mBindMenuBean.setPermission(permissionKey);
        return this;
    }

    /**
     * 设置菜单权限组
     *
     * @param permissionKeys
     * @return
     */
    public MenuOwnerHelper setPermissionKeys(List<String> permissionKeys) {
        mBindMenuBean.setPermissions(permissionKeys);
        return this;
    }

    /**
     * 权限改变监听
     *
     * @param onPermissionChangeListener
     */
    public MenuOwnerHelper addOnPermissionChangeListener(OnPermissionChangeListener onPermissionChangeListener) {
        if (onPermissionChangeListener != null) {
            mListener.add(onPermissionChangeListener);
        }
        return this;
    }

    public void setMenuCallback(Callback<NavigationMenu> menuCallback) {
        this.menuCallback = menuCallback;
    }

    /**
     * 获取权限回掉监听
     *
     * @return
     */
    public List<OnPermissionChangeListener> getOnPermissionChangeListeners() {
        return mListener;
    }


    /**
     * 获取菜单
     */
    public void loadMenu() {
        String path = mBindMenuBean.getPath();
        if (!TextUtils.isEmpty(path)) {
            getMenuByPath(path, new Callback<>() {
                @Override
                public void onSuccess(NavigationMenu menu) {
                    mMenu = menu;
                    if (menuCallback != null) {
                        menuCallback.onSuccess(menu);
                    }
                }

                @Override
                public void onFailure(String error) {
                    if (menuCallback != null) {
                        menuCallback.onFailure(error);
                    }
                }
            });
        }
    }


    /**
     * 获取权限
     */
    public void loadPermission() {
        if(mMenuRepository==null)return;
        String permission = mBindMenuBean.getPermission();
        List<String> permissions = mBindMenuBean.getPermissions();
        List<String> keys = new ArrayList<>();
        if (!TextUtils.isEmpty(permission)) {
            keys.add(permission);
        }
        if (permissions != null && !permissions.isEmpty()) {
            keys.addAll(permissions);
        }
        if (!keys.isEmpty()) {
            mMenuRepository.getPermissionInKeys(keys, new Callback<List<ViewPermission>>() {
                @Override
                public void onSuccess(List<ViewPermission> permissions) {
                    mPermissions.clear();
                    if (permissions != null && !permissions.isEmpty()) {
                        mPermissions.addAll(permissions);
                    }
                    invokePermissionCallback();
                }

                @Override
                public void onFailure(String error) {
                    invokePermissionCallback();
                }
            });
        }
    }

    /**
     * 回掉
     */
    public void invokePermissionCallback() {
        if (!mListener.isEmpty()) {
            for (OnPermissionChangeListener item : mListener) {
                if (item != null) {
                    item.onPermissionChange();
                }
            }
        }
    }


    /**
     * 根据path查询菜单
     *
     * @param path
     * @param callback
     */
    public void getMenuByPath(String path, @NonNull Callback<NavigationMenu> callback) {
        if(mMenuRepository==null)return;
        mMenuRepository.getMenuByPath(path, callback);
    }

    /**
     * 根据上级菜单id查询子菜单
     *
     * @param id
     * @param callback
     */
    public void getChildrenByParentId(String id, @NonNull Callback<List<NavigationMenu>> callback) {
        if(mMenuRepository==null)return;
        mMenuRepository.getChildrenByParentId(id, callback);
    }

    /**
     * 根据上级菜单id查询子菜单
     *
     * @param id
     * @param callback
     */
    public void getChildrenByParentId(String id, int level, @NonNull Callback<List<NavigationMenu>> callback) {
        if(mMenuRepository==null)return;
        mMenuRepository.getChildrenByParentId(id, level, callback);
    }

    /**
     * 根据上级菜单path查询子菜单
     *
     * @param path
     * @param callback
     */
    public void getChildrenByParentPath(String path, int level, @NonNull Callback<List<NavigationMenu>> callback) {
        if(mMenuRepository==null)return;
        mMenuRepository.getChildrenByParentPath(path, level, callback);
    }

    /**
     * 根据上级菜单path查询子菜单
     *
     * @param path
     * @param callback
     */
    public void getChildrenByParentPath(String path, @NonNull Callback<List<NavigationMenu>> callback) {
        if(mMenuRepository==null)return;
        mMenuRepository.getChildrenByParentPath(path, callback);
    }


    public @Nullable NavigationMenu getMenu() {
        return mMenu;
    }

    /**
     * 获取权限
     *
     * @param permission
     * @return
     */
    public @NonNull ViewPermission getPermission(@Nullable String permission) {
        if (permission == null) return ViewPermission.EMPTY;
        for (int i = 0; i < mPermissions.size(); i++) {
            ViewPermission viewPermission = mPermissions.get(i);
            if (Objects.equals(viewPermission.getKey(), permission)) {
                return viewPermission;
            }
        }
        return ViewPermission.EMPTY;
    }

    /**
     * 获取主要权限
     *
     * @return
     */
    public @NonNull ViewPermission getPermission() {
        if (!TextUtils.isEmpty(mBindMenuBean.getPermission())) {
            return getPermission(mBindMenuBean.getPermission());
        }
        return !mPermissions.isEmpty() ? mPermissions.get(0) : ViewPermission.EMPTY;
    }

    public @NonNull List<ViewPermission> getPermissions() {
        return mPermissions;
    }

    /**
     * 默认菜单权限字符串
     *
     * @return
     */
    public String getPermissionText() {
        return getPermission().getPermissionText();
    }
    /**
     * 默认菜单权限 添加
     *
     * @return
     */
    public boolean isAddPermission() {
        return getPermission().isAddPermission();
    }

    /**
     * 默认菜单权限 修改
     *
     * @return
     */
    public boolean isUpdatePermission() {
        return getPermission().isUpdatePermission();
    }

    /**
     * 默认菜单权限 审核
     *
     * @return
     */
    public boolean isAuditPermission() {
        return getPermission().isAuditPermission();
    }

    /**
     * 默认菜单权限 删除
     *
     * @return
     */
    public boolean isDeletePermission() {
        return getPermission().isDeletePermission();
    }

    /**
     * 所有权限菜单中是否包含权限 添加
     *
     * @return
     */
    public boolean hasAddPermission() {
        if (!mPermissions.isEmpty()) {
            for (ViewPermission permission : mPermissions) {
                if (permission.isAddPermission()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 所有权限菜单中是否包含权限 修改
     *
     * @return
     */
    public boolean hasUpdatePermission() {
        if (!mPermissions.isEmpty()) {
            for (ViewPermission permission : mPermissions) {
                if (permission.isUpdatePermission()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 所有权限菜单中是否包含权限 审核
     *
     * @return
     */
    public boolean hasAuditPermission() {
        if (!mPermissions.isEmpty()) {
            for (ViewPermission permission : mPermissions) {
                if (permission.isAuditPermission()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 所有权限菜单中是否包含权限 删除
     *
     * @return
     */
    public boolean hasDeletePermission() {
        if (!mPermissions.isEmpty()) {
            for (ViewPermission permission : mPermissions) {
                if (permission.isDeletePermission()) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * 销毁
     */
    public void onDestroy() {
        if (mMenuRepository != null) {
            mMenuRepository.unDisposable();
            mMenuRepository = null;
        }
        mListener.clear();
    }

    /**
     * 从BindMenu中解析菜单配置
     */
    private void parseBindMenu() {
        BindMenu bindMenu = getDeclaredAnnotation(BindMenu.class);
        if (bindMenu != null) {
            mBindMenuBean.setName(bindMenu.name());
            mBindMenuBean.setCode(bindMenu.code());
            mBindMenuBean.setPath(bindMenu.path());
            mBindMenuBean.setPermission(bindMenu.permission());
            String[] permissions = bindMenu.permissions();
            mBindMenuBean.setPermissions(permissions != null && permissions.length > 0 ? Arrays.asList(permissions) : null);
        }

    }


    /**
     * @noinspection unchecked
     */
    private <A extends Annotation> A getDeclaredAnnotation(@NonNull Class<A> annotationClass) {
        if (mOwner == null) return null;
        Class<?> mTargetClass = mOwner.getClass();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return mTargetClass.getDeclaredAnnotation(annotationClass);
        } else {
            Annotation[] annotations = mTargetClass.getDeclaredAnnotations();
            for (Annotation annotation : annotations) {
                if (annotation.annotationType() == annotationClass) {
                    return (A) annotation;
                }
            }
        }
        return null;
    }

}
